using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
using System.Diagnostics;

namespace Axe.Web.Security.Membership.Implementation
{
    /// <summary>
    /// Summary description for SqlPasswordResetRequestManager
    /// </summary>
    public class SqlPasswordResetRequestManager : PasswordResetRequestManager
    {
        string connectionString;
        string requestTableName = "PassResetRequests";

        public override bool RegisterRequest(string username, out Guid reqKey)
        {
            reqKey = Guid.NewGuid();

            SqlConnection sqlConn = new SqlConnection(connectionString);
            SqlCommand cmd = sqlConn.CreateCommand();

            cmd.CommandText = "INSERT INTO [" + requestTableName + "] (UserName,RequestKey,RequestDate,IsApproved) VALUES (@UserName,@RequestKey,@RequestDate,@IsApproved)";

            cmd.Parameters.AddWithValue("@UserName", username);
            cmd.Parameters.AddWithValue("@RequestKey", reqKey);
            cmd.Parameters.AddWithValue("@RequestDate", DateTime.Now);
            cmd.Parameters.AddWithValue("@IsApproved", false);

            try
            {
                sqlConn.Open();
                int affectedRows = cmd.ExecuteNonQuery();
                return (affectedRows == 1);
            }
            catch (SqlException sqle)
            {
                Debug.WriteLine(sqle.Message);
                return false;
            }
            finally
            {
                if (sqlConn != null)
                    sqlConn.Close();
            }
        }

        public override bool IsLocked(Guid requestKey)
        {
            SqlCommand cmd = new SqlCommand();

            cmd.CommandText = "SELECT IsApproved FROM [" + requestTableName + "] WHERE RequestKey = @RequestKey";
            cmd.Parameters.AddWithValue("@RequestKey", requestKey);

            SqlConnection conn = new SqlConnection(connectionString);

            bool isLocked;

            try
            {
                cmd.Connection = conn;
                conn.Open();

                isLocked = (bool)cmd.ExecuteScalar();

                return isLocked;
            }
            catch (SqlException sqle)
            {
                Debug.Write(sqle.Message);
            }
            finally
            {
                if (conn != null)
                    conn.Close();
            }

            return true;
        }

        public override bool HasRequest(Guid requestKey)
        {
            SqlCommand cmd = new SqlCommand();

            cmd.CommandText = "SELECT COUNT(*) FROM [" + requestTableName + "] WHERE RequestKey = @RequestKey";
            cmd.Parameters.AddWithValue("@RequestKey", requestKey);

            SqlConnection conn = new SqlConnection(connectionString);

            try
            {
                cmd.Connection = conn;
                conn.Open();

                int count = (int)cmd.ExecuteScalar();

                if (count == 0)
                    return false;
                else
                    return true;
            }
            catch (SqlException sqle)
            {
                Debug.WriteLine(sqle.Message);
                return false;
            }
            finally
            {
                if (conn != null)
                    conn.Close();
            }
        }

        public override bool LockRequest(Guid requestKey)
        {
            if (HasRequest(requestKey) == false)
                return false;

            SqlCommand cmd = new SqlCommand();

            cmd.CommandText = "UPDATE [" + requestTableName + "] SET IsApproved=1 WHERE RequestKey = @RequestKey";
            cmd.Parameters.AddWithValue("@RequestKey", requestKey);

            SqlConnection conn = new SqlConnection(connectionString);

            try
            {
                cmd.Connection = conn;
                conn.Open();

                int affectedRows = cmd.ExecuteNonQuery();

                if (affectedRows == 0)
                    return false;
                else
                    return true;
            }
            catch (SqlException sqle)
            {
                Debug.WriteLine(sqle.Message);
            }
            finally
            {
                if (conn != null)
                    conn.Close();
            }

            return true;
        }

        public override PassResetStatus ValidateRequest(string username, Guid requestKey)
        {
            if (HasRequest(requestKey) == false)
                return PassResetStatus.InvalidRequestKey;

            SqlConnection conn = new SqlConnection(connectionString);
            SqlCommand cmd = conn.CreateCommand();

            cmd.CommandText = "SELECT UserName,IsApproved,RequestDate FROM [" + requestTableName + "] WHERE RequestKey = @RequestKey";
            cmd.Parameters.AddWithValue("@RequestKey", requestKey);

            try
            {
                conn.Open();

                using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
                {
                    if (reader.HasRows && reader.Read())
                    {
                        string originalUserName = (string)reader["UserName"];
                        bool isApproved = (bool)reader["IsApproved"];
                        DateTime requestDate = (DateTime)reader["RequestDate"];

                        TimeSpan requestSpan = DateTime.Now - requestDate;

                        if (isApproved)
                            return PassResetStatus.RequestLocked;
                        /*
                        if (requestSpan > Globals.Settings.PassResetConfiguration.RequestExpirationTime)
                            return PassResetStatus.RequestExpired;
                        */
                        if (username != originalUserName)
                            return PassResetStatus.InvalidUserName;

                        return PassResetStatus.Success;
                    }
                    else
                    {
                        return PassResetStatus.ProviderException;
                    }
                }
            }
            catch (SqlException e)
            {
                Debug.WriteLine(e.Message);
                return PassResetStatus.ProviderException;
            }
            finally
            {
                conn.Close();
            }
        }

        public SqlPasswordResetRequestManager(string connStr)
        {
            connectionString = connStr;
        }
    }
}